package ntd.util.frame.storage.impl;

import cn.hutool.log.StaticLog;
import io.minio.MinioClient;
import io.minio.policy.PolicyType;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import ntd.util.config.common.exception.ComException;
import ntd.util.frame.storage.NtdStorage;
import ntd.util.frame.storage.bo.StorageConfig;
import ntd.util.UtilCatch;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

@Slf4j
@Data
public class NtdStorageMinio implements NtdStorage {

    private StorageConfig config;

    private MinioClient minioClient;

    public NtdStorageMinio(StorageConfig config) {
        this.config = config;
        try {
            minioClient = new MinioClient(config.getUrl(), config.getAppKey(), config.getAppSecret());
        } catch (Exception e) {
            StaticLog.error(e, "[minio][file]文件服务器连接失败...");
            throw new ComException("文件服务器链接失败 - " + e.getMessage());
        }
    }

    @Override
    public void store(String bucketName, byte[] bytes, String keyName) {
        initBucket(bucketName);
        try {
            minioClient.putObject(bucketName, keyName, new ByteArrayInputStream(bytes), "application/octet-stream");
        } catch (Exception e) {
            StaticLog.error(e, "[minio][文件存储]执行失败...");
            throw new ComException("文件存储失败 - " + e.getMessage());
        }
    }

    @Override
    public InputStream loadInputStream(String bucketName, String name) {
        return UtilCatch.tryCatch(() -> minioClient.getObject(bucketName, name));
    }

    private void initBucket(String bucketName) {
        try {
            if(!minioClient.bucketExists(bucketName)) {
                minioClient.makeBucket(bucketName);
                minioClient.setBucketPolicy(bucketName, "private", PolicyType.READ_WRITE);
            }
        } catch (Exception e) {
            StaticLog.error(e, "[minio][存储桶初始化]失败...");
            throw new ComException("存储桶初始化失败 - " + e.getMessage());
        }
    }

    @Override
    public void delete(String bucketName, String keyName) {
        UtilCatch.tryCatchNoRes(() -> minioClient.removeObject(bucketName, keyName));
    }

    @Override
    public String generateUrl(String bucketName, String keyName) {
        return config.getUrl() + "/" + bucketName + "/" + keyName;
    }
}
